home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Language/OS - Multiplatform Resource Library
/
LANGUAGE OS.iso
/
t3_1
/
risc_src.lha
/
risc_sources
/
link
/
mipsco_link.t
< prev
next >
Wrap
Text File
|
1989-06-30
|
12KB
|
346 lines
(herald mipsco_link (env t (link defs)))
;;; Look at a Unix a.out description and template.doc
(define (link modules out-spec)
(really-link modules 'mbo out-spec 'o))
(define-constant RELOC-SIZE 8)
(define-constant MAGIC #x160)
(define-constant TEXT-SYM 1)
(define-constant DATA-SYM 3)
(lset reloc-length 0)
(lset pure-size 0)
(define-constant %%d-ieee-size 53)
(define-constant %%d-ieee-excess 1023)
(define (write-double-float stream float)
(receive (sign mantissa exponent)
(normalized-float-parts float
%%d-ieee-size
%%d-ieee-excess
t)
(write-int stream header/double-float)
(write-half stream (fx+ (fixnum-ashl sign 15)
(fx+ (fixnum-ashl exponent 4)
(bignum-bit-field mantissa 48 4))))
(write-half stream (bignum-bit-field mantissa 32 16))
(write-half stream (bignum-bit-field mantissa 16 16))
(write-half stream (bignum-bit-field mantissa 0 16))))
(define (write-vcell-header var stream)
(write-half stream 0)
(write-byte stream (if (fx= (vector-length (var-node-refs var))
0)
0
-1))
(write-byte stream (if (eq? (var-node-defined var) 'define)
(fx+ header/vcell 128)
header/vcell)))
(define (vgc-copy-foreign foreign)
(let* ((heap (lstate-impure *lstate*))
(addr (area-frontier heap))
(name (foreign-object-name foreign))
(desc (object nil
((heap-stored self) (lstate-impure *lstate*))
((heap-offset self) addr)
((write-descriptor self stream)
(write-data stream (fx+ addr tag/extend)))
((write-store self stream)
(write-int stream header/foreign)
(write-slot name stream)
(write-int stream 0)))))
(set (area-frontier heap) (fx+ addr 12))
(set-table-entry *reloc-table* foreign desc)
(generate-slot-relocation name (fx+ addr 4))
(push (area-objects heap) desc)
(cymbal-thunk (symbol->string name) 0)
(reloc-thunk (fx+ addr 8) (lstate-symbol-count *lstate*) 5)
(modify (lstate-symbol-count *lstate*) (lambda (x) (fx+ x 1)))
desc))
(define (relocate-unit-variable var addr external?)
(let ((area (lstate-impure *lstate*))
(type (var-value-type var)))
(cond (type
(cond ((and external? (neq? (var-node-value var) NONVALUE))
(cymbal-thunk (string-downcase! (symbol->string (var-node-name var)))
(unit-var-value (var-node-value var)))
(modify (lstate-symbol-count *lstate*) (lambda (x) (fx+ x 1)))))
(if (fx= type DATA-SYM)
(reloc-thunk addr DATA-SYM 4)
(reloc-thunk addr TEXT-SYM 4))))))
(define (var-value-type var)
(let ((value (var-node-value var)))
(cond ((eq? value NONVALUE)
(vgc (var-node-name var))
nil)
((unit-loc? value) DATA-SYM)
(else
(let ((desc (vgc value)))
(if (eq? (heap-stored desc) (lstate-impure *lstate*))
DATA-SYM
TEXT-SYM))))))
(define (generate-slot-relocation obj slot-address)
(cond ((or (fixnum? obj) (char? obj) (eq? obj '#t)))
((eq? (heap-stored (vgc obj)) (lstate-impure *lstate*))
(reloc-thunk slot-address DATA-SYM 4))
(else
(reloc-thunk slot-address TEXT-SYM 4))))
(define (text-relocation addr)
(reloc-thunk addr TEXT-SYM 4))
(define (data-relocation addr)
(reloc-thunk addr DATA-SYM 4))
(define (reloc-thunk address lw hb)
(push (lstate-data-reloc *lstate*)
(cons address (cons lw hb))))
(lset the-string-table nil)
(define (cymbal-thunk stryng value)
(push (lstate-symbols *lstate*)
(object (lambda (stream)
(write-int stream 0)
(write-int stream (table-entry the-string-table stryng))
(cond ((fx= value 0) ; undefined external (foreign)
(write-int stream 0)
(write-half stream #x4cf))
(else
(write-data stream value)
(write-half stream #x44f)))
(write-half stream #xffff))
((cymbal-thunk.stryng self) stryng))))
(define-operation (cymbal-thunk.stryng thunk))
(define (write-slot obj stream)
(cond ((table-entry *reloc-table* obj)
=> (lambda (desc) (write-descriptor desc stream)))
((fixnum? obj)
(write-fixnum stream obj))
((char? obj)
(write-int stream (fx+ (fixnum-ashl (char->ascii obj) 8)
header/char)))
((eq? obj '#t)
(write-int stream header/true))
(else
(error "bad immediate type ~s" obj))))
(define-integrable (write-data stream int)
(write-int stream (fx+ pure-size int)))
(define-integrable (write-int stream int)
(write-half stream (fixnum-ashr int 16))
(write-half stream int))
(define (write-half stream int)
(write-byte stream (fixnum-ashr int 8))
(write-byte stream int))
(define-integrable (write-byte stream n)
(writec stream (ascii->char (fixnum-logand n 255))))
(define-integrable (write-fixnum stream fixnum)
(write-half stream (fixnum-ashr fixnum 14))
(write-half stream (fixnum-ashl fixnum 2)))
(define (write-link-file stream)
(set reloc-length (enforce (lambda (x) (<= x #xffff))
(length (lstate-data-reloc *lstate*))))
(modify (lstate-symbols *lstate*) reverse!)
(pad-area (lstate-pure *lstate*))
(pad-area (lstate-impure *lstate*))
(set pure-size (area-frontier (lstate-pure *lstate*)))
(write-header stream)
(write-aouthdr stream)
(write-text-section-header stream)
(write-data-section-header stream)
(write-area stream (lstate-pure *lstate*))
(write-area stream (lstate-impure *lstate*))
(write-relocation stream)
(receive (i aligned-i) (make-stryng-table)
(write-cymbal-table-header stream aligned-i)
(write-hack-local-symbol stream)
(write-hack-local-string stream)
(write-stryng-table stream (fx- aligned-i i)))
(write-hack-file-descriptor stream)
(write-cymbal-table stream))
(define (write-header stream)
(write-half stream MAGIC) ;magic number
(write-half stream 2) ; # of sections
(write-int stream 0) ; time and date
(write-int stream (cymbal-table-offset))
(write-int stream #x60) ;size of symbol header
(write-half stream #x38) ; size of a.out header
(write-half stream 0)) ;flags
(define (write-aouthdr stream)
(write-half stream #x107) ;magic
(write-half stream #x11f) ;version stamp
(write-int stream (text-size)) ;text size
(write-int stream (data-size)) ;data size
(write-int stream 0) ;bss size
(write-int stream 0) ;entry
(write-int stream 0) ;text base
(write-int stream (text-size)) ;data base
(write-int stream (+ (text-size) (data-size))) ;bss base
(write-int stream 0) ;register mask
(write-int stream 0) ;cp mask [4]
(write-int stream 0)
(write-int stream 0)
(write-int stream 0)
(write-int stream #x8010)) ;gp value ???
(define (write-text-section-header stream)
(write-string stream ".text")
(write-byte stream 0)
(write-byte stream #x20)
(write-byte stream #x20)
(write-int stream 0) ; phys addr
(write-int stream 0) ; virtual addr
(write-int stream (text-size))
(write-int stream (headers-size)) ;offset in file
(write-int stream 0) ; no reloc
(write-int stream 0) ; no gp table
(write-int stream 0)
(write-int stream #x20))
(define (write-data-section-header stream)
(write-string stream ".data")
(write-byte stream 0)
(write-byte stream #x20)
(write-byte stream #x20)
(write-int stream (text-size)) ; phys addr
(write-int stream (text-size)) ; virtual addr
(write-int stream (data-size))
(write-int stream (+ (text-size) (headers-size))) ;offset in file
(write-int stream (+ (headers-size) (text-size) (data-size))) ; reloc
(write-int stream 0) ; no gp table
(write-half stream reloc-length)
(write-half stream 0) ;no gp tables
(write-int stream #x40))
(define (headers-size) (fx* 39 4))
(define (text-size) (area-frontier (lstate-pure *lstate*)))
(define (data-size) (area-frontier (lstate-impure *lstate*)))
(define (cymbal-table-offset)
(+ (headers-size) (text-size) (data-size)
(* RELOC-SIZE reloc-length)))
(define (write-area stream area)
(walk (lambda (x) (write-store x stream))
(reverse! (area-objects area))))
(define (write-relocation stream)
(walk (lambda (item)
(destructure (((addr . (lw . hb)) item))
(write-data stream (car item))
(write-byte stream 0)
(write-half stream lw)
(write-byte stream hb)))
(sort-list! (lstate-data-reloc *lstate*)
(lambda (x y)
(fx< (car x) (car y))))))
(define (write-map-entry stream name value) nil)
(define (write-cymbal-table-header stream string-table-size)
(write-half stream #x7009) ;magic
(write-half stream #x11f) ;vstamp
(write-long-zeros stream 7)
(write-int stream 2) ;number of local symbols
(write-int stream (+ (cymbal-table-offset) #x60))
(write-long-zeros stream 4)
(write-int stream 8) ;max index in local strings
(write-int stream (+ (cymbal-table-offset) #x60 24))
(write-int stream string-table-size) ;max string-index
(write-int stream (+ (cymbal-table-offset) #x60 8 24)) ;string table begin
(write-int stream 1) ;fd entries
(write-int stream (+ (cymbal-table-offset) #x60 8 24 string-table-size))
(write-long-zeros stream 2)
(write-int stream (lstate-symbol-count *lstate*)) ;max symbol index
(write-int stream (+ (cymbal-table-offset) #x60 8 24 string-table-size 72)))
(define (write-hack-local-symbol stream)
(write-int stream 1)
(write-int stream 0)
(write-half stream #x2c20)
(write-half stream 2)
(write-int stream 1)
(write-int stream 0)
(write-half stream #x2020)
(write-half stream 0))
(define (write-hack-local-string stream)
(write-byte stream 0)
(write-string stream "foo.s")
(write-byte stream 0)
(write-byte stream 0))
(define (write-hack-file-descriptor stream)
(walk (lambda (x) (write-int stream x))
'(0 1 0 7 0 2 0 0 0 0 0 0 0 0 0))
(write-half stream #x1d80)
(write-half stream 0)
(write-int stream 0)
(write-int stream 0))
(define (write-long-zeros stream n)
(do ((i n (fx- i 1)))
((fx= i 0))
(write-int stream 0)))
(define (write-cymbal-table stream)
(walk (lambda (cym) (cym stream)) (lstate-symbols *lstate*)))
(define (make-stryng-table)
(set the-string-table (make-string-table 'stryngs))
(iterate loop ((i 0) (cyms (lstate-symbols *lstate*)))
(cond ((null? cyms) (return i (align i 2)))
(else
(let* ((string (cymbal-thunk.stryng (car cyms)))
(len (string-length string)))
(set (table-entry the-string-table string) i)
(loop (fx+ i (fx+ len 1)) (cdr cyms)))))))
(define (write-stryng-table stream extra)
(walk (lambda (cym)
(write-string stream (cymbal-thunk.stryng cym))
(write-byte stream 0))
(lstate-symbols *lstate*))
(do ((extra extra (fx- extra 1)))
((fx= extra 0))
(write-byte stream 0)))
(define (pad-area area)
(let ((rem (fixnum-remainder (area-frontier area) 16)))
(cond ((fxn= rem 0)
(modify (area-frontier area)
(lambda (x) (fx+ x (fx- 16 rem))))
(do ((i (fx- 16 rem) (fx- i 4)))
((fx= i 0))
(push (area-objects area)
(object nil
((write-store self stream)
(write-int stream 0)))))))))